package models

import (
	"TeacherManager/common"
	"database/sql"
	"strconv"
	"time"
)

/**
* Created by LONG  on 2018/5/28.
 */

type Exam struct {
	ExamID    uint    `gorm:"primary_key"`
	Title     string  // title
	DesCrib   string  `gorm:"default:'暂时没有描述哦'"`
	StartTime string  `gorm:"index;not null;"`
	EndTime   string  `gorm:"index;not null;"`
	TeacherID uint    `gorm:"teacherindex;not null;"` //教师ID  外键 (属于), tag `teacherindex`是为该列创建索引 非空
	ClassID   uint    `gorm:"classindex;not null;"`   //班级ID  外键 (属于), tag `classindex`是为该列创建索引 非空
	Classes   []Class `gorm:"many2many:exam_class;"`  // Many-To-Many , 'exam_class'是连接表
	//Students     []Student   `gorm:"many2many:exam_stu;"`    // Many-To-Many , 'exam_stu'是连接表
	//ExamScores   []ExamScore `gorm:"many2many:exam_score;"`    // Many-To-Many , 'exam_score'是连接表
	Degree       int  `gorm:"default:1"` //难度系数 1简单 2中等 3 难度 4自定义
	Add_Sub      bool `gorm:"default:false"`
	Mul_Div      bool `gorm:"default:false"`
	Fraction     bool `gorm:"default:false"` //是否带分数
	Pt           bool `gorm:"default:false"` //是否带括号
	MaxNumOfOper int  `gorm:"default:2"`     //最大运算符个数	默认2个
	CalNums      int  `gorm:"default:10"`    //运算数取值范围 默认10以内
	QuesNums     int  `gorm:"default:10"`    //题目个数 默认10个
	IsPublished  bool `gorm:"default:false"` // published or not

	DegreeName string `gorm:"-"`
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

type ExamScore struct {
	BaseModel
	Score     int
	ExamID    uint `gorm:"index"` // 外键 (属于), tag `index`是为该列创建索引
	StudentID uint `gorm:"index"`
}

func ListAllPubExam(teacherid uint) ([]*Exam, error) {
	return _listExam(teacherid, true)
}
func ListAllUnPubExam(teacherid uint) ([]*Exam, error) {
	return _listExam(teacherid, false)
}
func _listExam(teacherid uint, published bool) ([]*Exam, error) {
	var exams []*Exam
	var err error
	if published {
		err = DB.Where("is_published = ? and teacher_id = ?", true, teacherid).Find(&exams).Error
	} else {
		err = DB.Where("is_published = ? and teacher_id = ?", false, teacherid).Find(&exams).Error
	}
	return exams, err
}

func (e *Exam) DeleteExam() error {
	return DB.Delete(e).Error
}

func (c *Exam) GetLastExamID() (error error, id uint) {
	var examtem Exam
	err := DB.Last(&examtem).Error
	return err, examtem.ExamID
}

// insert exam
func (e *Exam) Insert() error {
	return DB.Create(e).Error
}

//get ctime by id
func (e *Exam) GetCreateTimeById() error {
	return DB.Where("exam_id = ? ", e.ExamID).Find(e).Error
}

func InsertExamWithClass(classes []string, examid uint) error {
	var err error
	var rows2 *sql.Rows
	var total int
	for _, val := range classes {
		var classid int
		classid, err = strconv.Atoi(val)
		rows2, err = DB.Raw("select count(*) as total from exam_class where exam_exam_id = ?  and class_class_id = ?  ", examid, classid).Rows()
		if err != nil {
			return err
		}
		defer rows2.Close()
		for rows2.Next() {
			rows2.Scan(&total)
		}

		if total > 0 {

		} else {
			err = DB.Exec("INSERT INTO exam_class (exam_exam_id, class_class_id) VALUES (?,?)", examid, uint(classid)).Error
			err = DB.Exec("UPDATE classes SET exam_nums=exam_nums+1 WHERE class_id IN (?)", uint(classid)).Error
		}

	}
	return err

}

//db.Model(&exam).Related(&classes, "Classes") 等价于下列的sql语句
// SELECT * FROM classes INNER JOIN exam_class
//ON  exam_class.class_class_id = classes.class_id WHERE exam_class.exam_exam_id = 3

func (e *Exam) UpdateClassExamNums() error {
	var err error
	var classes []Class
	DB.Model(&e).Related(&classes, "Classes")
	err = DB.Exec("DELETE FROM exam_scores WHERE  exam_id IN (?)", e.ExamID).Error
	err = DB.Exec("DELETE FROM exam_class WHERE  exam_exam_id IN (?)", e.ExamID).Error
	for _, val := range classes {
		var classid = val.ClassID
		err = DB.Exec("UPDATE classes SET exam_nums=exam_nums-1 WHERE class_id IN (?)", uint(classid)).Error
	}
	return err
}

func (e *Exam) GetClassByExamId() ([]common.Classmsg, error) {
	var err error
	var rows *sql.Rows
	rows, err = DB.Raw("select class_class_id from exam_class where exam_exam_id IN (?)  ", e.ExamID).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	mytem := make([]common.Classmsg, 0)
	for rows.Next() {
		var classid int
		var classname string
		rows.Scan(&classid)
		rows2, err := DB.Raw("select class_name from classes where class_id IN (?)  ", classid).Rows()
		if err != nil {
			return nil, err
		}
		defer rows2.Close()
		for rows2.Next() {
			rows2.Scan(&classname)
		}
		var msg common.Classmsg = common.Classmsg{
			ID:   classid,
			Text: classname,
		}
		mytem = append(mytem, msg)
	}
	return mytem, err
}

//update  exam
func (c *Exam) UpdateExam(flag bool) error {
	var err error
	var change = map[string]interface{}{"title": c.Title,
		"des_crib": c.DesCrib, "start_time": c.StartTime, "end_time": c.EndTime}
	if flag {
		change["is_published"] = c.IsPublished
	}
	err = DB.Model(c).Updates(
		change).Error
	//err = DB.Save(&c).Error
	//err = DB.Where("class_id = ?", c.ClassID).Find(&classtem).Error
	return err
}

func UnpublishExam(eid int) error {
	var err error
	err = DB.Exec("UPDATE exams SET is_published=false, start_time='', end_time = '' WHERE exam_id IN (?)", uint(eid)).Error
	err = DB.Exec("DELETE FROM exam_class WHERE  exam_exam_id IN (?)", uint(eid)).Error
	return err
}

func (e *Exam) GetExamByID() error {
	var err error
	return DB.Where("exam_id = ? ", e.ExamID).Find(e).Error
	return err
}
